package hh.util;

import java.util.HashMap;
import java.util.Map;

@SuppressWarnings({"unchecked", "rawtypes"})
public interface BaseEnum<E extends Enum> {


    Map<Class<Enum>, Enum[]> enums = new HashMap<>(1024);



    static void register(Enum[] values) {
        Class<? extends Enum> aClass = values[0].getClass();
        if (!enums.containsKey(aClass)) {
            enums.put((Class<Enum>) aClass, values);
        }
    }

    String getChineseName();

    String getEnglishName();

    Integer getCode();

    String getDesc();

    E fromCnName(String cnName);

    E fromCnNameIgnoreCase(String cnName);

    E fromEnName(String enName);

    E fromEnNameIgnoreCase(String enName);

    E fromCode(Integer code);

    enum TestEnum implements BaseEnum<TestEnum> {
        Red(1, "红色", "red", "红色");

        private Integer code;
        private String chineseName;
        private String englishName;
        private String desc;


        static Map<String, TestEnum> enNameToEnum = new HashMap<>();
        static Map<String, TestEnum> cnNameToEnum = new HashMap<>();
        static Map<Integer, TestEnum> codeToEnum = new HashMap<>();

        static {
            TestEnum[] values = values();
            for (TestEnum e : values) {
                enNameToEnum.put(e.englishName, e);
                cnNameToEnum.put(e.chineseName, e);
                codeToEnum.put(e.code, e);
            }
            register(values);
        }

        TestEnum(Integer code, String chineseName, String englishName, String desc) {
            this.code = code;
            this.chineseName = chineseName;
            this.englishName = englishName;
            this.desc = desc;
        }

        @Override
        public String getChineseName() {
            return chineseName;
        }

        @Override
        public String getEnglishName() {
            return englishName;
        }

        @Override
        public Integer getCode() {
            return code;
        }

        @Override
        public String getDesc() {
            return desc;
        }

        @Override
        public TestEnum fromCnName(String cnName) {
            return cnNameToEnum.get(cnName);
        }

        @Override
        public TestEnum fromCnNameIgnoreCase(String cnName) {
            if (cnName == null)
                return null;
            for (Map.Entry<String, TestEnum> e : cnNameToEnum.entrySet()) {
                if (cnName.equalsIgnoreCase(e.getKey()))
                    return e.getValue();
            }
            return null;
        }

        @Override
        public TestEnum fromEnName(String enName) {
            return enNameToEnum.get(enName);
        }

        @Override
        public TestEnum fromEnNameIgnoreCase(String enName) {
            if (enName == null)
                return null;
            for (Map.Entry<String, TestEnum> e : enNameToEnum.entrySet()) {
                if (enName.equalsIgnoreCase(e.getKey()))
                    return e.getValue();
            }
            return null;
        }

        @Override
        public TestEnum fromCode(Integer code) {
            return codeToEnum.get(code);
        }

        @Override
        public String toString() {
            return this.getClass().getSimpleName() + "{" +
                    "code=" + code +
                    ", chineseName='" + chineseName + '\'' +
                    ", englishName='" + englishName + '\'' +
                    ", desc='" + desc + '\'' +
                    '}';
        }
    }
}
